From 8c52f78fc55c09d78327e5be822b0e131d1be33d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 1 Mar 2006 18:33:36 +0100 Subject: [PATCH] Disallow cmpxchg8b ptwr emulation for non-pae. Also a few cleanups. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 1e29ce5d2d..05d7704211 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -507,10 +507,9 @@ get_page_from_l2e( rc = get_page_and_type_from_pagenr( l2e_get_pfn(l2e), PGT_l1_page_table | vaddr, d); -#if CONFIG_PAGING_LEVELS == 2 - if ( unlikely(!rc) ) + if ( (CONFIG_PAGING_LEVELS == 2) && unlikely(!rc) ) rc = get_linear_pagetable(l2e, pfn, d); -#endif + return rc; } @@ -539,10 +538,10 @@ get_page_from_l3e( rc = get_page_and_type_from_pagenr( l3e_get_pfn(l3e), PGT_l2_page_table | vaddr, d); -#if CONFIG_PAGING_LEVELS == 3 - if ( unlikely(!rc) ) + + if ( (CONFIG_PAGING_LEVELS == 3) && unlikely(!rc) ) rc = get_linear_pagetable(l3e, pfn, d); -#endif + return rc; } #endif /* 3 level */ @@ -3187,8 +3186,8 @@ static int ptwr_emulated_update( ptwr_flush(d, PTWR_PT_INACTIVE); /* Read the PTE that maps the page being updated. */ - if (__copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)], - sizeof(pte))) + if ( __copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)], + sizeof(pte)) ) { MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table"); return X86EMUL_UNHANDLEABLE; @@ -3198,15 +3197,10 @@ static int ptwr_emulated_update( page = mfn_to_page(pfn); /* We are looking only for read-only mappings of p.t. pages. */ - if ( ((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) != _PAGE_PRESENT) || - ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) || - (page_get_owner(page) != d) ) - { - MEM_LOG("ptwr_emulate: Page is mistyped or bad pte " - "(%lx, %" PRtype_info ")", - l1e_get_pfn(pte), page->u.inuse.type_info); - return X86EMUL_UNHANDLEABLE; - } + ASSERT((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) == _PAGE_PRESENT); + ASSERT((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table); + ASSERT((page->u.inuse.type_info & PGT_count_mask) != 0); + ASSERT(page_get_owner(page) == d); /* Check the new PTE. */ nl1e = l1e_from_intpte(val); @@ -3266,8 +3260,11 @@ static int ptwr_emulated_cmpxchg8b( unsigned long new, unsigned long new_hi) { - return ptwr_emulated_update( - addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1); + if ( CONFIG_PAGING_LEVELS == 2 ) + return X86EMUL_UNHANDLEABLE; + else + return ptwr_emulated_update( + addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1); } static struct x86_mem_emulator ptwr_mem_emulator = { -- 2.30.2